package sg.edu.ntu.bloch.tictactoe.view;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Scanner;

import org.apache.log4j.Logger;

import sg.edu.ntu.bloch.tictactoe.datasource.player.PlayerSource;
import sg.edu.ntu.bloch.tictactoe.datasource.player.PlayerSourceFactory;
import sg.edu.ntu.bloch.tictactoe.engine.Board;
import sg.edu.ntu.bloch.tictactoe.engine.Player;
import sg.edu.ntu.bloch.tictactoe.engine.Seed;
import sg.edu.ntu.bloch.tictactoe.engine.State;

public class ConsoleView implements Viewable {

	private static final Logger _log = Logger.getLogger(ConsoleView.class);
	private String welcome;
	private String menu;
	private PlayerSource playerSource;
	int maxSize;
	int maxPlayer;

	public ConsoleView() throws Exception {
		welcome = String.format("Welcome to TicTacToe verison %d revision %d ",
				0, 1);
		StringBuilder sb = new StringBuilder();
		sb.append("======= Menu =======").append("\n");
		sb.append("1) New Game").append("\n");
		sb.append("2) Continue Game").append("\n");
		sb.append("3) New Player").append("\n");
		sb.append("4) Quit").append("\n");
		sb.append("====================").append("\n");
		menu = sb.toString();
		_log.debug("Menu is " + menu);
		playerSource = PlayerSourceFactory.getInstance()
				.getPlayerSourceInstance();
		InputStream is = ClassLoader
				.getSystemResourceAsStream("tictactoe.properties");
		Properties prop = new Properties();
		prop.load(is);
		this.maxSize = Integer.parseInt(prop.getProperty("board.max.size"));
		this.maxPlayer = Integer.parseInt(prop.getProperty("board.max.player"));
		_log.debug("View Created : Console, maxSize: " + this.maxSize
				+ " maxPlayer: " + maxPlayer);
	}

	@Override
	public void initialize() {
		boolean notQuit = true;
		System.out.println(welcome);
		Scanner in = new Scanner(System.in);
		String _input;
		int input;
		do {
			System.out.println(menu);
			System.out.println("Your Choice: ");
			_input = in.nextLine();
			try {
				input = Integer.parseInt(_input);
			} catch (Exception e) {
				input = -1;
			}
			switch (input) {
			case 1:
				createGame(in);
				break;
			case 2:
				System.out.println("Not Supported yet");
				continue;
			case 3:
				createPlayer(in);
				break;
			case 4:
				quit();
				notQuit = false;
				break;
			default:
				System.out.println("Please enter a valid choice");
				break;
			}
		} while (notQuit);
	}

	@Override
	public void quit() {
		System.out.println("Thank you for playing TicTacToe v0r1");
	}

	private void createGame(Scanner in) {
		List<Player> playerList = new ArrayList<Player>();
		int boardSize = 0;
		boolean validPlayer = false;
		do {
			validPlayer = false;
			System.out.format("Please enter player %d registered name ",
					playerList.size() + 1);
			String playerName = in.next();
			Player player = playerSource.getPlayer(playerName);

			if (playerName.trim().isEmpty()) {
				System.out.println("Please enter your registered name.");
			} else if (player == null) {
				System.out
						.println("Unable find selected player, do you want to add that player ? Y/N");
				String toRegister = in.next();
				if (toRegister != null
						&& toRegister.trim().equalsIgnoreCase("Y")) {
					player = new Player(toRegister);
					playerSource.newPlayer(player);
					validPlayer = true;
				} else {
					System.out.println("Player not added.");
				}
			} else if (playerList.contains(player)) {
				System.out.format("Player %s already included "
						+ "in the game ", player);
			} else {
				validPlayer = true;
			}
			if (validPlayer)
				playerList.add(player);
		} while (playerList.size() < maxPlayer);

		do {
			System.out.format("Please enter a valid desired board "
					+ "size [Max Allow size is %d", maxSize);
			String input = in.next();
			try {
				boardSize = Integer.parseInt(input);
			} catch (Exception e) {
				boardSize= 0;
			}
			_log.debug("Size is " + boardSize);
		} while (boardSize <= 0 || boardSize > maxSize);
		Board board = new Board(playerList, boardSize);
		Game game = new Game(board);
		game.play();
	}

	private void createPlayer(Scanner in) {
		Player player = null;
		String name = "";
		do {
			System.out.format("Please enter your desired Username", maxSize);
			if (in.hasNext()) {
				name = in.next();
				if (playerSource.unqiueName(name)) {
					player = new Player(name);
				}
			}
		} while (player == null);
		playerSource.newPlayer(player);
	}

	private void load() {
		// TODO Auto-generated method stub

	}

	class Game {
		private final Board board;
		private Scanner in = new Scanner(System.in);

		public Game(Board board) {
			this.board = board;
		}

		public void play() {
			Player nextPlayer = null;
			Seed seed = null;
			State state = null;
			int x = -1;
			int y = -1;
			do {
				nextPlayer = board.getCurrentPlayer();
				do {
					System.out.println(nextPlayer.getPlayer()
							+ ", please enter the coordinate "
							+ "for your next seed ");
					System.out.print("X: ");
					x = -1;
					// possible to refactor
					do {
						if (in.hasNextInt()) {
							x = in.nextInt();
						} else {
							System.out.println("Please enter a valid "
									+ "integer for X coordinate");
						}
					} while (x < 0);
					System.out.print("Y: ");
					y = -1;
					do {
						if (in.hasNextInt()) {
							y = in.nextInt();
						} else {
							System.out.println("Please enter a valid "
									+ "integer for Y coordinate");
						}
					} while (y < 0);
				} while (board.isSlotEmpty(x, y) == false);
				seed = new Seed(nextPlayer, x, y);
				state = board.put(seed);
			} while (State.CONTINUE.equals(state));
		}
	}

}
